#pragma once
#include "gp_XY.h"

class gp_Dir2d;
class gp_XY;
class gp_Pnt2d;
class gp_Ax2d;
class gp_Trsf2d;


//!  Defines a non-persistent vector in 2D space. <br>
class gp_Vec2d  {

public:

  //! Creates a zero vector. <br>
      gp_Vec2d();
  //! Creates a unitary vector from a direction V. <br>
      gp_Vec2d(const gp_Dir2d& V);
  //! Creates a vector with a doublet of coordinates. <br>
      gp_Vec2d(const gp_XY& Coord);
  //! Creates a point with its two cartesian coordinates. <br>
      gp_Vec2d(const double Xv,const double Yv);
  
//!  Creates a vector from two points. The length of the vector <br>
//!  is the distance between P1 and P2 <br>
      gp_Vec2d(const gp_Pnt2d& P1,const gp_Pnt2d& P2);
  //! Changes the coordinate of range Index <br>
//!  Index = 1 => X is modified <br>
//!  Index = 2 => Y is modified <br>
//! Raises OutOfRange if Index != {1, 2}. <br>
        void SetCoord(const int Index,const double Xi) ;
  //! For this vector, assigns <br>
//!   the values Xv and Yv to its two coordinates <br>
        void SetCoord(const double Xv,const double Yv) ;
  //! Assigns the given value to the X coordinate of this vector. <br>
        void SetX(const double X) ;
  //! Assigns the given value to the Y coordinate of this vector. <br>
        void SetY(const double Y) ;
  //! Assigns the two coordinates of Coord to this vector. <br>
        void SetXY(const gp_XY& Coord) ;
  
//!  Returns the coordinate of range Index : <br>
//!  Index = 1 => X is returned <br>
//!  Index = 2 => Y is returned <br>//! Raised if Index != {1, 2}. <br>
        double Coord(const int Index) const;
  //!  For this vector, returns  its two coordinates Xv and Yv <br>
        void Coord(double& Xv,double& Yv) const;
  //! For this vector, returns its X  coordinate. <br>
        double X() const;
  //! For this vector, returns its Y  coordinate. <br>
        double Y() const;
  //! For this vector, returns its two coordinates as a number pair <br>
       const gp_XY& XY() const;
  
//!  Returns True if the two vectors have the same magnitude value <br>
//!  and the same direction. The precision values are LinearTolerance <br>
//!  for the magnitude and AngularTolerance for the direction. <br>
       bool IsEqual(const gp_Vec2d& Other,const double LinearTolerance,const double AngularTolerance) const;
  
//!  Returns True if abs(Abs(<me>.Angle(Other)) - PI/2.) <br>
//!  <= AngularTolerance <br>
//! Raises VectorWithNullMagnitude if <me>.Magnitude() <= Resolution or <br>
//!  Other.Magnitude() <= Resolution from gp. <br>
        bool IsNormal(const gp_Vec2d& Other,const double AngularTolerance) const;
  
//!  Returns True if PI - Abs(<me>.Angle(Other)) <= AngularTolerance <br>
//!  Raises VectorWithNullMagnitude if <me>.Magnitude() <= Resolution or <br>
//!  Other.Magnitude() <= Resolution from gp. <br>
        bool IsOpposite(const gp_Vec2d& Other,const double AngularTolerance) const;
  
//!  Returns true if Abs(Angle(<me>, Other)) <= AngularTolerance or <br>
//!  PI - Abs(Angle(<me>, Other)) <= AngularTolerance <br>
//!  Two vectors with opposite directions are considered as parallel. <br>
//!  Raises VectorWithNullMagnitude if <me>.Magnitude() <= Resolution or <br>
//!  Other.Magnitude() <= Resolution from gp <br>
        bool IsParallel(const gp_Vec2d& Other,const double AngularTolerance) const;
  
//!  Computes the angular value between <me> and <Other> <br>
//!  returns the angle value between -PI and PI in radian. <br>
//!  The orientation is from <me> to Other. The positive sense is the <br>
//!  trigonometric sense. <br>
//!    Raises VectorWithNullMagnitude if <me>.Magnitude() <= Resolution from gp or <br>
//!  Other.Magnitude() <= Resolution because the angular value is <br>
//!  indefinite if one of the vectors has a null magnitude. <br>
       double Angle(const gp_Vec2d& Other) const;
  //!  Computes the magnitude of this vector. <br>
        double Magnitude() const;
  //!  Computes the square magnitude of this vector. <br>
        double SquareMagnitude() const;
  
        void Add(const gp_Vec2d& Other) ;
      void operator +=(const gp_Vec2d& Other) 
{
  Add(Other);
}
  //! Adds two vectors <br>
        gp_Vec2d Added(const gp_Vec2d& Other) const;
      gp_Vec2d operator +(const gp_Vec2d& Other) const
{
  return Added(Other);
}
  //! Computes the crossing product between two vectors <br>
        double Crossed(const gp_Vec2d& Right) const;
      double operator ^(const gp_Vec2d& Right) const
{
  return Crossed(Right);
}
  
//!  Computes the magnitude of the cross product between <me> and <br>
//!  Right. Returns || <me> ^ Right || <br>
        double CrossMagnitude(const gp_Vec2d& Right) const;
  
//!  Computes the square magnitude of the cross product between <me> and <br>
//!  Right. Returns || <me> ^ Right ||**2 <br>
        double CrossSquareMagnitude(const gp_Vec2d& Right) const;
  
        void Divide(const double Scalar) ;
      void operator /=(const double Scalar) 
{
  Divide(Scalar);
}
  //! divides a vector by a scalar <br>
        gp_Vec2d Divided(const double Scalar) const;
      gp_Vec2d operator /(const double Scalar) const
{
  return Divided(Scalar);
}
  //! Computes the scalar product <br>
        double Dot(const gp_Vec2d& Other) const;
      double operator *(const gp_Vec2d& Other) const
{
  return Dot(Other);
}
  
        gp_Vec2d GetNormal() const;
  
        void Multiply(const double Scalar) ;
      void operator *=(const double Scalar) 
{
  Multiply(Scalar);
}
  //! Normalizes a vector <br>
//!  Raises an exception if the magnitude of the vector is <br>
//!  lower or equal to Resolution from package gp. <br>
        gp_Vec2d Multiplied(const double Scalar) const;
      gp_Vec2d operator *(const double Scalar) const
{
  return Multiplied(Scalar);
}
  
        void Normalize() ;
  //! Normalizes a vector <br>
//!  Raises an exception if the magnitude of the vector is <br>
//!  lower or equal to Resolution from package gp. <br>//! Reverses the direction of a vector <br>
        gp_Vec2d Normalized() const;
  
        void Reverse() ;
  //! Reverses the direction of a vector <br>//! Subtracts two vectors <br>
        gp_Vec2d Reversed() const;
      gp_Vec2d operator -() const
{
  return Reversed();
}
  
        void Subtract(const gp_Vec2d& Right) ;
      void operator -=(const gp_Vec2d& Right) 
{
  Subtract(Right);
}
  //! Subtracts two vectors <br>
        gp_Vec2d Subtracted(const gp_Vec2d& Right) const;
      gp_Vec2d operator -(const gp_Vec2d& Right) const
{
  return Subtracted(Right);
}
  
//!  <me> is setted to the following linear form : <br>
//!  A1 * V1 + A2 * V2 + V3 <br>
        void SetLinearForm(const double A1,const gp_Vec2d& V1,const double A2,const gp_Vec2d& V2,const gp_Vec2d& V3) ;
  
//!  <me> is setted to the following linear form : A1 * V1 + A2 * V2 <br>
        void SetLinearForm(const double A1,const gp_Vec2d& V1,const double A2,const gp_Vec2d& V2) ;
  
//!  <me> is setted to the following linear form : A1 * V1 + V2 <br>
        void SetLinearForm(const double A1,const gp_Vec2d& V1,const gp_Vec2d& V2) ;
  
//!  <me> is setted to the following linear form : Left + Right <br>
//!  Performs the symmetrical transformation of a vector <br>
//!  with respect to the vector V which is the center of <br>
//!  the  symmetry. <br>
        void SetLinearForm(const gp_Vec2d& Left,const gp_Vec2d& Right) ;
  
       void Mirror(const gp_Vec2d& V) ;
  
//!  Performs the symmetrical transformation of a vector <br>
//!  with respect to the vector V which is the center of <br>
//!  the  symmetry. <br>
//!  Performs the symmetrical transformation of a vector <br>
//!  with respect to an axis placement which is the axis <br>
//!  of the symmetry. <br>
       gp_Vec2d Mirrored(const gp_Vec2d& V) const;
  
       void Mirror(const gp_Ax2d& A1) ;
  
//!  Performs the symmetrical transformation of a vector <br>
//!  with respect to an axis placement which is the axis <br>
//!  of the symmetry. <br>
       gp_Vec2d Mirrored(const gp_Ax2d& A1) const;
  
        void Rotate(const double Ang) ;
  
//!  Rotates a vector. Ang is the angular value of the <br>
//!  rotation in radians. <br>
        gp_Vec2d Rotated(const double Ang) const;
  
        void Scale(const double S) ;
  //! Scales a vector. S is the scaling value. <br>
        gp_Vec2d Scaled(const double S) const;
  
       void Transform(const gp_Trsf2d& T) ;
  //! Transforms a vector with a Trsf from gp. <br>
        gp_Vec2d Transformed(const gp_Trsf2d& T) const;
    const gp_XY& _CSFDB_Getgp_Vec2dcoord() const { return coord; }

private: 
	gp_XY coord;

};
